package com.wechat.service.storage;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.swak.annotation.FluxService;
import com.swak.entity.Page;
import com.swak.entity.Parameters;
import com.swak.entity.YesNo;
import com.swak.persistence.OrderBy;
import com.swak.persistence.QueryCondition;
import com.swak.service.BaseService;
import com.swak.utils.Lists;
import com.swak.utils.StringUtils;
import com.swak.utils.time.DateTimes;
import com.wechat.dto.ChatDTO;
import com.wechat.dto.ChatRoomDTO;
import com.wechat.dto.ContactDTO;
import com.wechat.dto.ContactFindDTO;
import com.wechat.entity.Contact;
import com.wechat.enums.ContactType;
import com.wechat.service.ChatRoomService;
import com.wechat.service.ChatService;
import com.wechat.service.ContactService;
import com.wechat.service.storage.mapper.ContactMapper;
import com.wechat.utils.PinYin4jUtils;

/**
 * 描述
 * 
 * @author Auto Generator
 * @date 2022-10-21T23:59:27.258522100
 */
@FluxService
@Service("wechatContactService")
public class ContactServiceImpl extends BaseService<Contact, String> implements ContactService {

	@Autowired
	private ContactMapper contactMapper;
	@Autowired
	private ChatService chatService;
	@Autowired
	private ChatRoomService roomService;

	/**
	 * 直取
	 */
	@Override
	public ContactDTO get(String id) {
		return ContactDTO.convert(this.contactMapper.get(id));
	}

	@Override
	public List<ContactDTO> create(List<ContactDTO> contacts) {
		ContactServiceImpl me = this.getProxy();
		List<ContactDTO> adds = Lists.newArrayList();
		for (ContactDTO contact : contacts) {
			adds.add(me.create(contact));
		}
		return adds;
	}

	/**
	 * 保存
	 */
	@Override
	@Transactional
	public ContactDTO create(ContactDTO contact) {
		Contact entity = contact.transform() //
				.setPyInitial(PinYin4jUtils
						.headByString(StringUtils.defaultIfBlank(contact.getAlias(), contact.getNickName())))//
				.setPyName(PinYin4jUtils.pinyinByString(contact.getNickName()))//
				.setPyAlias(PinYin4jUtils.pinyinByString(contact.getAlias()))//
				.setVerifyFlag(0) // 权限
				.setIsStar(YesNo.No.getType());// 是否星标好友
		this.contactMapper.insertive(entity, true);
		return this.get(entity.getId());
	}

	/**
	 * 删除
	 */
	@Override
	@Transactional
	public Integer delete(ContactDTO contact) {
		Contact entity = contact.transform();
		return this.contactMapper.delete(entity);
	}

	/**
	 * 分页查询
	 */
	@Override
	@Transactional
	public Page<ContactDTO> page(ContactDTO query, Parameters param) {
		QueryCondition qc = new QueryCondition();
		qc.getCriteria().andEqualTo(Contact.DelFlag, Boolean.FALSE);
		qc.setOrderByClause(param.orderBy(Contact.DefaultOrderBy));
		return ContactDTO.convert(this.contactMapper.queryForPage(qc, param));
	}

	@Override
	@Transactional
	public List<ContactDTO> friends(ContactFindDTO find) {
		QueryCondition qc = new QueryCondition();
		qc.getCriteria().andEqualTo(Contact.DelFlag, Boolean.FALSE);
		qc.getCriteria().andEqualTo(Contact.IsFriend, YesNo.Yes.getType());
		if (StringUtils.isNotBlank(find.getName())) {
			qc.orCriteria().andLike(Contact.NickName, find.getName());
		}
		if (StringUtils.isNotBlank(find.getName())) {
			qc.orCriteria().andLike(Contact.PyName, find.getName());
		}
		qc.setOrderByClause(OrderBy.of().Desc(Contact.IsStar).Asc(Contact.PyInitial));
		return ContactDTO.convert(this.contactMapper.queryByCondition(qc));
	}

	@Override
	@Transactional
	public List<ContactDTO> friendAdds(ContactFindDTO find) {
		QueryCondition qc = new QueryCondition();
		qc.getCriteria().andEqualTo(Contact.DelFlag, Boolean.FALSE);
		qc.getCriteria().andIsNotNull(Contact.AddDate);
		qc.getCriteria().andDateGreaterThan(Contact.AddDate, DateTimes.getDateByNowOffset(30));
		if (StringUtils.isNotBlank(find.getName())) {
			qc.orCriteria().andLike(Contact.NickName, find.getName());
		}
		if (StringUtils.isNotBlank(find.getName())) {
			qc.orCriteria().andLike(Contact.PyName, find.getName());
		}
		qc.setOrderByClause(OrderBy.of().Desc(Contact.AddDate));
		return ContactDTO.convert(this.contactMapper.queryByCondition(qc));
	}

	@Override
	@Transactional
	public ContactDTO saveNickName(ContactDTO contact) {

		// 保存昵称
		Contact.of().setId(contact.getId()).setNickName(contact.getNickName()).updateSelective();
		Contact saved = Contact.of().setId(contact.getId()).get();

		// 修改备注名拼音
		Contact.of().setId(contact.getId())
				.setPyInitial(
						PinYin4jUtils.headByString(StringUtils.defaultIfBlank(saved.getAlias(), saved.getNickName())))//
				.setPyName(PinYin4jUtils.pinyinByString(saved.getNickName()))//
				.setPyAlias(PinYin4jUtils.pinyinByString(saved.getAlias()))//
				.updateSelective();

		// 同步昵称数据
		this.chatService.syncNickName(ChatDTO.of()
				.setNickName(StringUtils.defaultIfBlank(saved.getAlias(), saved.getNickName())).setId(contact.getId()));

		// 同步昵称到聊天室
		if (saved.getType() == ContactType.Chat_Room.getType()) {
			this.roomService.syncNickName(ChatRoomDTO.of().setNickName(saved.getNickName()).setId(saved.getId()));
		}

		return this.get(contact.getId());
	}

	@Override
	@Transactional
	public ContactDTO saveAlias(ContactDTO contact) {

		// 修改备注
		Contact.of().setId(contact.getId()).setAlias(contact.getAlias()).updateSelective();
		Contact saved = Contact.of().setId(contact.getId()).get();

		// 修改备注名拼音
		Contact.of().setId(contact.getId())
				.setPyInitial(
						PinYin4jUtils.headByString(StringUtils.defaultIfBlank(saved.getAlias(), saved.getNickName())))//
				.setPyName(PinYin4jUtils.pinyinByString(saved.getNickName()))//
				.setPyAlias(PinYin4jUtils.pinyinByString(saved.getAlias()))//
				.updateSelective();

		// 同步昵称
		this.chatService.syncNickName(ChatDTO.of()
				.setNickName(StringUtils.defaultIfBlank(saved.getAlias(), saved.getNickName())).setId(contact.getId()));

		return this.get(contact.getId());
	}

	@Override
	@Transactional
	public ContactDTO saveRemarks(ContactDTO contact) {
		Contact.of().setId(contact.getId()).setRemarks(contact.getRemarks()).updateSelective();
		return this.get(contact.getId());
	}

	@Override
	@Transactional
	public ContactDTO removeFromFriend(ContactDTO contact) {
		Contact.of().setId(contact.getId()).setIsFriend(YesNo.No.getType()).updateSelective();
		this.chatService.syncIsFriend(ChatDTO.of().setIsFriend(YesNo.No.getType()).setId(contact.getId()));
		return this.get(contact.getId());
	}

	@Override
	@Transactional
	public List<ContactDTO> contacts(List<String> userNames) {
		QueryCondition qc = new QueryCondition();
		qc.getCriteria().andEqualTo(Contact.DelFlag, Boolean.FALSE);
		qc.getCriteria().andIn(Contact.Id, userNames);
		qc.setOrderByClause(OrderBy.of().Asc(Contact.CreateDate));
		return ContactDTO.convert(this.contactMapper.queryByCondition(qc));
	}

	// ******************* 同步数据，不要级联更新其他数据 ******************

	@Override
	@Transactional
	public void syncIsFriend(ContactDTO contact) {
		Contact.of().setId(contact.getId()).setIsFriend(contact.getIsFriend()).updateSelective();
	}

}
